import { getHostiles } from "../../../global/map";
import { roleTower } from "../../../role/tower";
import { errLog } from "../../../util/log";
import { GroupWorkers } from "../terminal/workers";
import { GroupCluster, newGroup} from "./cluster";
import { ClusterDefenders } from "./defenders";
import { ClusterStructure } from "./structure";

/**
 * @deprecated
 */
export class ClusterSingleRoom extends GroupCluster{
    forceSingleRoomDomain(){
        let expected = {
            domain:[this.spawnRoomName]
        }
        let mem = this.spawnRoom.memory;
        if(!mem){
            Memory.rooms[this.spawnRoomName] = expected;
            return;
        }
        if(mem.domain instanceof Array && mem.domain.length === 1){
            return;
        }
        mem.domain = expected.domain;
    }

    constructor(spawnRoom=undefined){
        super(spawnRoom);
        if(spawnRoom!==undefined){
            this.init(spawnRoom);
        }
    }
    init(spawnRoom){
        this.forceSingleRoomDomain();
        this.workerGroup = new GroupWorkers(spawnRoom);
        this.defenderGroup = new ClusterDefenders(spawnRoom);
        this.structureGroup = new ClusterStructure(spawnRoom);
    }
    serialize(){
        return {
            cluster: super.serialize(), 
            workerGroup: (this.workerGroup.serialize()),
            defenderGroup: (this.defenderGroup.serialize()),
            structureGroup: (this.structureGroup.serialize()),
            // cluster: super.serialize(),
            // workerGroup: serializeGroup(this.workerGroup),
            // defenderGroup: serializeGroup(this.defenderGroup),
            // structureGroup: serializeGroup(this.structureGroup),
        };
    }
    deserialize(obj){
        super.deserialize(obj.cluster);
        this.workerGroup = newGroup(GroupWorkers, obj.workerGroup, this.spawnRoom);
        this.defenderGroup = newGroup(ClusterDefenders, obj.defenderGroup, this.spawnRoom);
        this.structureGroup = newGroup(ClusterStructure, obj.structureGroup, this.spawnRoom);
        this.forceSingleRoomDomain();
        this.spawnRoom.maxCreepCount = this.maxSize;
        return this;
    }
    isPanicing(){
        let targets = getHostiles(this.spawnRoom, false);
        return targets.length>0;
    }
    normalSpawn(){
        if(this.workerGroup.size/this.workerGroup.maxSize<0.3){
            return this.workerGroup.spawn();
        }

        if(this.structureGroup.size/this.structureGroup.maxSize<this.workerGroup.size/this.workerGroup.maxSize){
            return this.structureGroup.spawn();
        }

        if(this.structureGroup.size<this.structureGroup.maxSize){
            return this.structureGroup.spawn();
        }
        if(this.workerGroup.size<this.workerGroup.maxSize){
            return this.workerGroup.spawn();
        }
        if(this.defenderGroup.size<this.defenderGroup.maxSize){
            return this.defenderGroup.spawn();
        }

        return ERR_FULL;
    }
    panicSpawn(){
        if(this.workerGroup.size/this.workerGroup.maxSize<0.05){
            return this.workerGroup.spawn();
        }

        if(this.defenderGroup.size/this.defenderGroup.maxSize<this.workerGroup.size/this.workerGroup.maxSize){
            return this.defenderGroup.spawn();
        }

        if(this.structureGroup.size/this.structureGroup.maxSize<this.workerGroup.size/this.workerGroup.maxSize){
            return this.structureGroup.spawn();
        }

        if(this.structureGroup.size<this.structureGroup.maxSize){
            return this.structureGroup.spawn();
        }
        if(this.workerGroup.size<this.workerGroup.maxSize){
            return this.workerGroup.spawn();
        }
        if(this.defenderGroup.size<this.defenderGroup.maxSize){
            return this.defenderGroup.spawn();
        }

        return ERR_FULL;
    }
    spawn(){
        if(this.isPanicing()){
            return this.panicSpawn();
        }else{
            return this.normalSpawn();
        }
    }
    run(){
        try{
            this.defenderGroup.run();
        }catch(e){
            errLog(e);
        }
        try{
            this.workerGroup.run();
        }catch(e){
            errLog(e);
        }

        
        let roomName = this.spawnRoom.name;
        let room = Game.rooms[roomName];
        if(!room){
            return OK;
        }
        for(let tower of room.find(FIND_MY_STRUCTURES,{
            filter:(structure)=>structure.structureType===STRUCTURE_TOWER
        })){
            roleTower.run(tower);
        }
        return OK;
    }
}